package org.budo.excel.jdbc.driver.parser.jsqlparser;

import java.sql.SQLException;

import org.budo.excel.jdbc.driver.statement.impl.SHOW_FULL_TABLES;
import org.budo.excel.jdbc.driver.statement.impl.SHOW_TABLE_STATUS;
import org.budo.excel.jdbc.driver.statement.impl.SelectStatement;
import org.budo.jdbc.driver.exception.BudoJdbcDriverNotSupportedException;
import org.budo.jdbc.driver.parser.AbstractSqlStatementParser;
import org.budo.jdbc.driver.statement.JdbcStatement;

import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectBody;
import net.sf.jsqlparser.statement.update.Update;

/**
 * @author lmw
 */
public class JSqlParserExcelStatementParser extends AbstractSqlStatementParser {
    @Override
    public JdbcStatement parse(String sql) throws SQLException {
        String _sql = sql.trim().toUpperCase(); // 转大写
        if (_sql.startsWith("SHOW FULL TABLES")) {
            return new SHOW_FULL_TABLES();
        }

        if (_sql.startsWith("SHOW TABLE STATUS")) {
            return new SHOW_TABLE_STATUS();
        }

        return super.parse(sql);
    }

    @Override
    protected JdbcStatement doParseSql(String sql) throws Throwable {
        Statement statement = CCJSqlParserUtil.parse(sql);

        if (statement instanceof Insert) {
            return this.parseInsert(sql, (Insert) statement);
        }

        if (statement instanceof Update) {
            return this.parseUpdate(sql, (Update) statement);
        }

        if (statement instanceof Delete) {
            return this.parseDelete(sql, (Delete) statement);
        }

        if (statement instanceof Select) {
            return this.parseSelect(sql, statement);
        }

        throw new BudoJdbcDriverNotSupportedException("#106 not supported sql : " + sql //
                + ", statement=" + statement + ", type=" + statement.getClass());
    }

    private JdbcStatement parseSelect(String sql, Statement statement) {
        Select select = (Select) statement;
        SelectBody selectBody = select.getSelectBody();

        if (selectBody instanceof PlainSelect) {
            return this.parsePlainSelect(sql, statement, selectBody);
        }

        throw new BudoJdbcDriverNotSupportedException("#70 not supported sql(selectBody) : sql=" + sql //
                + ", statement=" + statement + ", type=" + statement.getClass() //
                + ", selectBody=" + selectBody + ", selectBody.type=" + selectBody.getClass());
    }

    private JdbcStatement parsePlainSelect(String sql, Statement statement, SelectBody selectBody) {
        return new SelectStatement();
    }

    private JdbcStatement parseDelete(String sql, Delete statement) {
        throw new RuntimeException();
    }

    private JdbcStatement parseUpdate(String sql, Update statement) {
        throw new RuntimeException();
    }

    private JdbcStatement parseInsert(String sql, Insert statement) {
        throw new RuntimeException();
    }
}